package com.fit.spring.boot.properties.autoscan.autoconfigure;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.Environment;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import com.fit.spring.boot.properties.autoscan.utils.IOUtil;



//
//			配置参数：
//					enabled				//是否开启自动扫描(默认true)
//					locations			//要自动加载的文件(默认值为null,不进行扫描).取值如:classpath*:**/*.properties(扫描根路径下所有的配置文件)
//					dev-locations		//开发模式下需要扫描的配置文件,多个用','逗号分隔
//					test-locations		//测试模式下需要扫描的配置文件,多个用','逗号分隔
//					pro-locations		//生产模式下需要扫描的配置文件,多个用','逗号分隔
//			
//			PS：扩展
//				META-INF/auto-scan-configuration.properties此文件用于程序扩展用,如在一个jar包中的程序,那么可以将以上配置项写入此文件中
//

/**
 * 自动扫描配置文件
 * @author hcl
 */
public class AutoScanPropertiesProperties {
	
	private static Logger log = LoggerFactory.getLogger(AutoScanPropertiesProperties.class);
	
	//配置前缀
	public final static String PROPERTIES_PREFIX = "properties.autoscan";
	
	//扩展配置文件路径
	private final static String AUTO_SCAN_CONFIG_FILE_PATH ="classpath*:META-INF/auto-scan-configuration.properties";
	
	
	
	
	//是否启用(默认值 true)
	private Boolean enabled = true;
	
	//要扫描的配置文件,多个用逗号","分割(默认不扫描)
	private String locations = "classpath*:**/*-auto.properties,classpath*:**/*-auto.yml,classpath*:**/*-auto.yaml";
	
//根据模式进行激活扫描的文件	
//一定是配置在classpath:application.properties 文件
//	此文件中的配置项spring.profiles.active = dev,则加载devLocations。如果等于了test,则加载testLocations。如果等于了prod,则加载 proLocations
	
	//dev 开发模式下要扫描的配置文件
	private String devLocations = "classpath*:**/*-dev.properties,classpath*:**/*-dev.yml,classpath*:**/*-dev.yaml";
	
	//test 测试模式下要扫描的配置文件
	private String testLocations = "classpath*:**/*-test.properties,classpath*:**/*-test.yml,classpath*:**/*-test.yaml";

	//pro 生产环境下要扫描的配置文件
	private String proLocations = "classpath*:**/*-prod.properties,classpath*:**/*-prod.yml,classpath*:**/*-prod.yaml";
	
	
	
	private AutoScanPropertiesProperties(){}
	
	/**
	 * 获取多个配置文件
	 * @return
	 */
	public static List<AutoScanPropertiesProperties> getAutoScanPropertiesProperties(){
		String prefix = PROPERTIES_PREFIX+".";
		
		List<AutoScanPropertiesProperties> list = new ArrayList<AutoScanPropertiesProperties>();
		
		try {
			PathMatchingResourcePatternResolver configProperties = new PathMatchingResourcePatternResolver();
			Resource[] configSources = configProperties.getResources(AUTO_SCAN_CONFIG_FILE_PATH);
			for(Resource resource : configSources){
				InputStream in = null;
				try{
					Properties p = new Properties();
					in = resource.getInputStream();
					p.load(in);
					AutoScanPropertiesProperties autoScanPropertiesProperties = new AutoScanPropertiesProperties();
					
					String enabled = p.getProperty(prefix + "enabled", autoScanPropertiesProperties.enabled.toString());
					if(enabled != null && enabled != ""){
						autoScanPropertiesProperties.enabled = Boolean.parseBoolean(enabled);
					}
					String locations = p.getProperty(prefix + "locations");
					if(locations != null && locations != ""){
						autoScanPropertiesProperties.locations = locations;
					}
					
					String devLocations = p.getProperty(prefix + SpringProfilesActiveType.DEV.getName() + "-locations");
					if(devLocations != null && devLocations != ""){
						autoScanPropertiesProperties.devLocations =  devLocations;
					}
					
					String testLocations = p.getProperty(prefix + SpringProfilesActiveType.TEST.getName() + "-locations");
					if(testLocations != null && testLocations != ""){
						autoScanPropertiesProperties.testLocations = testLocations;
					}
					
					String proLocations = p.getProperty(prefix + SpringProfilesActiveType.PROD.getName() + "-locations");
					if(proLocations != null && proLocations != ""){
						autoScanPropertiesProperties.proLocations = proLocations;
					}
					
					list.add(autoScanPropertiesProperties);
				}catch (Exception e){
					log.error("加载配置文件异常！",e);
				}finally{
					IOUtil.close(in);
				}
			}
			
		} catch (IOException e) {
			log.error("读取 '{}' 配置文件异常！",AUTO_SCAN_CONFIG_FILE_PATH,e);
		}
		return list;
	}

	
	/**
	 * 获取系统配置文件(springboot 自动加载的配置文件中的配置信息)
	 * @param environment
	 * @return
	 */
	public static AutoScanPropertiesProperties getMainSysProperties(Environment environment){
		String prefix = PROPERTIES_PREFIX+".";
		AutoScanPropertiesProperties autoScanPropertiesProperties = new AutoScanPropertiesProperties();
		
		String enabled = environment.getProperty(prefix + "enabled", autoScanPropertiesProperties.enabled.toString());
		if(enabled != null && enabled != ""){
			autoScanPropertiesProperties.enabled = Boolean.parseBoolean(enabled);
		}
		String locations = environment.getProperty(prefix + "locations");
		if(locations != null && locations != ""){
			autoScanPropertiesProperties.locations = locations;
		}
		
		String devLocations = environment.getProperty(prefix + SpringProfilesActiveType.DEV.getName() + "-locations");
		if(devLocations != null && devLocations != ""){
			autoScanPropertiesProperties.devLocations =  devLocations;
		}
		
		String testLocations = environment.getProperty(prefix + SpringProfilesActiveType.TEST.getName() + "-locations");
		if(testLocations != null && testLocations != ""){
			autoScanPropertiesProperties.testLocations = testLocations;
		}
		
		String proLocations = environment.getProperty(prefix + SpringProfilesActiveType.PROD.getName() + "-locations");
		if(proLocations != null && proLocations != ""){
			autoScanPropertiesProperties.proLocations = proLocations;
		}
		
		return autoScanPropertiesProperties;
	}
	
	public Boolean getEnabled() {
		return enabled;
	}
	public String getLocations() {
		return locations;
	}

	public String getDevLocations() {
		return devLocations;
	}

	public String getTestLocations() {
		return testLocations;
	}

	public String getProLocations() {
		return proLocations;
	}

	/**
	 * spring 活跃的配置文件类型
	 * @author hcl
	 *
	 */
	public enum SpringProfilesActiveType{
		
		DEV("dev"),
		TEST("test"),
		PROD("prod");
		//模式
		private String name;
		
		private SpringProfilesActiveType(String name){
			this.name = name.toLowerCase();
		}
		
		public String getName(){
			return this.name;
		}
		
	}
}
